package com.example.seckill.utils;

import com.example.seckill.common.Constants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Random;

/**
 * @Author: caowj1217
 * @Date: 2021/8/9上午10:58
 * @Description:
 */
public class RedisLock {

    private String key;
    private RedisClient redisClient;
    private boolean lock = true;
    public static final Random RANDOM = new Random();

    public RedisLock(String purpose, String key){
    	 this.key = purpose + "_" + key + "_lock";
    	 this.redisClient = RedisFactory.getDefaultClient();
    }

    public RedisLock(String purpose, String key,RedisClient client){
   	 this.key = purpose + "_" + key + "_lock";
   	 this.redisClient = RedisFactory.getDefaultClient();
   	 this.redisClient = client;
   }

    public boolean lock(long timeout,int expire){
        long nanoTime = System.nanoTime();
        timeout *= Constants.MILLI_NANO_TIME;
        try {
            //在timeout的时间范围内不断轮询锁
            while (System.nanoTime() - nanoTime < timeout){
                //锁不存在的话，设置锁并设置锁过期时间，即加锁
                if (this.redisClient.setnx(this.key,Constants.LOCKED) == 1){
                    this.redisClient.expire(key,expire);
                    this.lock = true;
                    return true;
                }
                System.out.println("出现锁等待");
                //短暂休眠，避免可能的活锁
                Thread.sleep(3,RANDOM.nextInt(30));
            }
        } catch (Exception e) {
            throw new RuntimeException("locking error",e);
        }
        return false;
    }

    public void unlock(){
        try {
            if (this.lock){
                redisClient.delKey(key);
            }
        } catch (Throwable e){

        }
    }
}
